﻿Imports TBCC.UtilityMobile
Public Class ServerAddressForm

#Region "New"
    Public Sub New()

        ' 此调用是 Windows 窗体设计器所必需的。
        InitializeComponent()

        ' 在 InitializeComponent() 调用之后添加任何初始化。
        ctrls(0) = Me.txtAddress1
        ctrls(1) = Me.txtAddress2
        ctrls(2) = Me.txtAddress3
        ctrls(3) = Me.txtAddress4
        ctrls(4) = Me.txtPort
    End Sub
#End Region

    Private Const AddressLength As Short = 4
    Private Const PortLength As Short = 1
    Private Const ServerAddress_Offset As Short = 2018

    Private _isModify As Boolean = False
    Private ctrls(AddressLength + PortLength - 1) As TextBox

    'Private BeginLoadData As New AsyncCallback(AddressOf LoadData)

    Private Sub ServerAddressForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.CenterToParent()
        SetModifyState(False)
        Me.btnModify.Enabled = False
        'BeginLoadData.BeginInvoke(Nothing, Nothing, Nothing)

        If Me.MyParentForm IsNot Nothing Then
            Me.MyParentForm.SetControlEnabled(False)
        End If
        Me.Timer1.Start()
    End Sub

    Private Sub btnModify_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnModify.Click
        Me.btnModify.Enabled = False
        If EnterModify() = False Then
            'msg.Show("其它地方正在修改参数,请稍后再试.")
            Me.btnModify.Enabled = True
            Exit Sub
        End If

        SetModifyState(True)
    End Sub

    Private Sub btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSave.Click
        If CheckValidate() = False Then
            Exit Sub
        End If

        Dim result As Boolean
        Me.Cursor = Cursors.WaitCursor
        _isSaving = True
        result = Save()
        _isSaving = False
        Me.Cursor = Cursors.Default
        If result Then
            SetModifyState(False)
            msg.Show("保存成功。")
            LoadData(Nothing)
        Else
            msg.ShowError("保存失败。")
        End If
    End Sub

    Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
        Me.TimerHeart.Stop()
        Me.Close()
    End Sub

    Private Sub SetModifyState(ByVal flag As Boolean)
        Me.txtAddress1.ReadOnly = Not flag
        Me.txtAddress2.ReadOnly = Not flag
        Me.txtAddress3.ReadOnly = Not flag
        Me.txtAddress4.ReadOnly = Not flag
        Me.txtPort.ReadOnly = Not flag

        Me.btnModify.Enabled = Not flag
        Me.btnSave.Enabled = flag
    End Sub

    Private Sub LoadData(ByVal ar As IAsyncResult)
        Dim buf() As UShort
        If g_test Then
            ReDim buf(ctrls.Length - 1)
            Dim r As New Random
            For i As Integer = 0 To buf.Length - 1
                buf(i) = r.Next(1, 10)
            Next
        Else
            buf = COMHelper.Instance.Send4UShort(g_netID, FunctionCode.WordWritableRead, ServerAddress_Offset, AddressLength + PortLength)
        End If


        If buf Is Nothing Then
            'Me.btnModify.Enabled = False
            Me.Invoke(New Action(Of Boolean)(AddressOf SetModify), False)
            msg.ShowError(g_strReadError)
            Exit Sub
        End If

        'Me.btnModify.Enabled = True
        Me.Invoke(New Action(Of Boolean)(AddressOf SetModify), True)


        Dim t As UShort
        Dim j As Integer
        For j = 0 To AddressLength - 1
            t = buf(j)

            If t >= 0 AndAlso t <= 255 Then
                ctrls(j).Text = t.ToString()
                ctrls(j).Tag = t.ToString()
            End If
        Next

        t = buf(buf.Length - 1)
        If t >= 0 AndAlso t <= 65535 Then
            ctrls(ctrls.Length - 1).Text = t.ToString()
            ctrls(ctrls.Length - 1).Tag = t.ToString()
        End If
    End Sub
    Private Sub SetModify(ByVal flag As Boolean)
        Me.btnModify.Enabled = flag
    End Sub

    Private Function CheckValidate() As Boolean
        '检查地址是否为空, 是否输入正确
        For i As Integer = 0 To ctrls.Length - 2
            Dim txt As TextBox = ctrls(i)
            If txt.TextLength <= 0 Then
                msg.ShowWarning("地址不能为空。")
                txt.SelectAll()
                txt.Focus()
                Return False
            Else
                Dim value As Byte
                Try
                    value = CByte(txt.Text)
                Catch ex As Exception
                    msg.ShowWarning("地址输入错误，每位数值应在0－255之间。")
                    txt.SelectAll()
                    txt.Focus()
                    Return False
                End Try
            End If
        Next

        '检测端口是否为空, 是否输入正确
        If Me.txtPort.TextLength <= 0 Then
            msg.ShowWarning("端口不能为空。")
            Me.txtPort.SelectAll()
            Me.txtPort.Focus()
            Return False
        Else
            Dim value As UShort
            Try
                value = CUShort(Me.txtPort.Text)
            Catch ex As Exception
                msg.ShowWarning("端口输入错误，数值应在0－65535之间。")
                Me.txtPort.SelectAll()
                Me.txtPort.Focus()
                Return False
            End Try
        End If

        Return True
    End Function


    Private Function Save() As Boolean
        For i As Integer = 0 To ctrls.Length - 1
            If ctrls(i).Text.Trim() <> ctrls(i).Tag.ToString().Trim() Then
                Dim result As Boolean
                result = Save(ServerAddress_Offset + i, CUShort(ctrls(i).Text))
                If result = False Then
                    Return False
                End If
            End If
        Next


        '设置修改使能变量
        If ParameterModifyClass.SetModifyConfirm(g_netID) = False Then
            Return False
        End If

        ' Me.TimerHeart.Stop()

        ''修改门变量
        'If ExitModify() = False Then
        '    Debug.Write("ExitModify错误")
        'End If

        Return True
    End Function

    Private Function save(ByVal index As UShort, ByVal value As UShort) As Boolean
        Dim offset As UShort = index + 1000
        Return COMHelper.Instance.Write(g_netID, FunctionCode.WordWrite, offset, value)
    End Function


    ''' <summary>
    ''' 进入修改
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function EnterModify() As Boolean
        If g_test Then
            _isModify = True
            Return True
        End If


        Dim result As Boolean
        result = ParameterModifyClass.EnterModify(g_netID)

        If result = False Then
            Return False
        End If

        ''开始发送心跳包
        'Me.TimerHeart.Start()

        _isModify = True

        Return True
    End Function


    ''' <summary>
    ''' 退出修改
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Private Function ExitModify() As Boolean
        '门变量置为1
        Dim result As Boolean
        result = ParameterModifyClass.ExitModify(g_netID)

        '停止发送心跳包
        Me.TimerHeart.Stop()

        _isModify = False

        Return True
    End Function


#Region "发送心跳包"

    '心跳包连续发送错误的次数
    Private _heartFailCount As Integer = 0

    '心跳值
    Private _heartValue As Short = 0

    '心跳值是否初始化
    Private _bheartValue As Boolean = False

    '是否正在发送心跳标志
    Private _heartSending As Boolean = False

    '是否正在保存标志
    Public Shared _isSaving As Boolean = False

    '心跳包地址
    Private _heartIncreamentAddress As UShort = 7063

    ''' <summary>
    ''' 发送心跳包
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub HeartSend()
        If _bheartValue = False Then
            Dim b() As Short
            b = COMHelper.Instance.Send4Short(g_netID, FunctionCode.WordWritableRead, _heartIncreamentAddress, 1)
            If b IsNot Nothing AndAlso b.Length = 1 Then
                _heartValue = b(0)
                _bheartValue = True
            Else
                Exit Sub
            End If
        End If

        _heartValue = (_heartValue + 1) Mod UShort.MaxValue

        Dim result As Boolean
        result = COMHelper.Instance.Write(g_netID, FunctionCode.WordWrite, _heartIncreamentAddress, _heartValue)

        If result Then
            _heartFailCount = 0
        Else
            _heartFailCount += 1
        End If

        If _heartFailCount > 10 Then
            '提示用户可能断开连接了.
        End If

    End Sub

    ''' <summary>
    ''' 心跳定时器Tick事件
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub TimerHeart_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerHeart.Tick
        If Not g_HeartSend Then
            Exit Sub
        End If

        If _heartSending OrElse _isSaving Then
            Exit Sub
        End If

        _heartSending = True
        Me.HeartSend()
        _heartSending = False
    End Sub

#End Region

    Private Sub txtPort_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles txtPort.KeyPress, txtAddress4.KeyPress, txtAddress3.KeyPress, txtAddress2.KeyPress, txtAddress1.KeyPress
        e.Handled = False
        If Not System.Text.RegularExpressions.Regex.IsMatch(e.KeyChar, "^\d$") AndAlso Asc(e.KeyChar) <> Keys.Back AndAlso Asc(e.KeyChar) <> Keys.Delete Then
            e.Handled = True
        End If
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        sender.Stop()
        LoadData(Nothing)
        If Me.MyParentForm IsNot Nothing Then
            Me.MyParentForm.SetControlEnabled(True)
        End If
    End Sub
End Class